#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <map>
#include <vector>
#include <errno.h>
#include <fcntl.h>
using namespace std;

#define PORT 8080
#define MAXSIZE 1024
#define BUFFSIZE 1024
// 设置文件描述符为非阻塞
int setnonblocking(int fd)
{
    int flags = fcntl(fd, F_GETFL);
    if (flags == -1)
        return -1;
    flags |= O_NONBLOCK;
    if (fcntl(fd, F_SETFL, flags) == -1)
        return -1;
    return 0;
}
std::map<std::string, std::string> translation_map = {{"Hello", "你好"}}; // 定义一个map，用来存储翻译关系
int main()
{
    int server_fd, newsocket;
    struct sockaddr_in address;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    char buffer[BUFFSIZE];

    // 创建服务器套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
    // 配置服务器地址结构体
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 绑定socket
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听socket
    if (listen(server_fd, 5) < 0)
    {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }
    // 创建epoll实例
    int epollfd = epoll_create(MAXSIZE);
    if (epollfd == -1)
    {
        perror("epoll_create failed");
        exit(EXIT_FAILURE);
    }
    struct epoll_event event;
    std::vector<struct epoll_event> events(MAXSIZE);
    event.data.fd = server_fd;
    event.events = EPOLLIN | EPOLLET; // ET模式

    // 将server socket设置成非阻塞
    if (setnonblocking(server_fd) == -1)
    {
        perror("setnonblocking failed");
        exit(EXIT_FAILURE);
    }
    // 添加server socket到epoll实例中
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, server_fd, &event) == -1)
    {
        perror("epoll_ctl failed");
        exit(EXIT_FAILURE);
    }

    for(;;)
    {
        int num_events = epoll_wait(epollfd, events.data(), MAXSIZE, -1);
        if (num_events == -1)
        {
            perror("epoll_wait failed");
            exit(EXIT_FAILURE);
        }
        for (int i = 0; i < num_events; i++)
        {
            if (events[i].data.fd == server_fd)
            {
                // 处理新连接
                while ((newsocket = accept(server_fd, (struct sockaddr *)&address, &addrlen)) >= 0)
                {
                    // 将新连接设置为非阻塞
                    if (setnonblocking(newsocket) == -1)
                    {
                        perror("setnonblocking failed");
                        exit(EXIT_FAILURE);
                    }
                    event.data.fd = newsocket;
                    event.events = EPOLLIN | EPOLLET;
                    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newsocket, &event) == -1)
                    {
                        perror("epoll_ctl failed");
                        exit(EXIT_FAILURE);
                    }
                }
                if (errno != EAGAIN && errno != EWOULDBLOCK)
                {
                    perror("accept failed");
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                // 处理读取事件
                while (1)
                {
                    int n = read(events[i].data.fd, buffer, BUFFSIZE);
                    if (n == 0)
                    {
                        // 客户端关闭连接
                        close(events[i].data.fd);
                        // 从epoll实例中删除该连接
                        addrlen = sizeof(struct sockaddr_in);
                        if (epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, NULL) == -1)
                        {
                            perror("epoll_ctl failed");
                            exit(EXIT_FAILURE);
                        }
                        break;
                    }
                    else if (n < 0)
                    {
                        if (errno == EAGAIN || errno == EWOULDBLOCK)
                        {
                            // 没有数据可读
                            continue;
                        }
                        else
                        {
                            // 出错
                            perror("read failed");
                            exit(EXIT_FAILURE);
                        }
                    }
                    else
                    {
                        // 有数据可读
                        cout<<"read "<<n<<" bytes"<<endl;
                        // cout<<"read data: "<<buffer<<endl;
                        buffer[n] = '\0';
                        std::string input = buffer;
                        std::string output;
                        if (translation_map.count(input) > 0)
                        {
                            output = translation_map[input];
                        }
                        else
                        {
                            output = "unknown word";
                        }
                        if (write(events[i].data.fd, output.c_str(), output.length()) <0)
                        {
                            perror("write failed");
                            exit(EXIT_FAILURE);
                        }
                    }
                }
            }
        }
    }
    close(server_fd);
    return 0;
}